package com.itheima.boottlias.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.boottlias.domain.dto.LoginDTO;
import com.itheima.boottlias.domain.pojo.Emp;
import com.itheima.boottlias.domain.pojo.EmpExpr;
import com.itheima.boottlias.domain.pojo.EmpLog;
import com.itheima.boottlias.domain.query.QueryParam;
import com.itheima.boottlias.domain.vo.LoginVO;
import com.itheima.boottlias.domain.vo.PageResult;
import com.itheima.boottlias.ex.CustomException;
import com.itheima.boottlias.mapper.EmpExprMapper;
import com.itheima.boottlias.mapper.EmpMapper;
import com.itheima.boottlias.service.EmpLogService;
import com.itheima.boottlias.service.EmpService;
import com.itheima.boottlias.utils.JwtUtils;
import com.itheima.oss.AliyunOSSOperator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 员工业务实现
 * @author ghy
 * @version 1.0
 * @since 2025-07-11 15:01
 */
@Service
@Slf4j
public class EmpServiceImpl implements EmpService {

    @Autowired
    private EmpMapper empMapper;
    @Autowired
    private EmpExprMapper empExprMapper;
    @Autowired
    private EmpLogService empLogService;
    @Autowired
    private AliyunOSSOperator aliyunOSSOperator;


    /**
     * 分页查询
     *
     * @param queryParam
     * @return
     */
    @Override
    public PageResult<Emp> pageQuery(QueryParam queryParam) {
        // // 总条数
        // Long total = empMapper.count();
        // // 当前页集合
        // Integer start = (page-1) * pageSize;
        // List<Emp> rows = empMapper.pageQuery(start, pageSize);


        // 拦截器：拦截查询SQL语句，在执行查询前先进行统计数量，再执行查询的同时为其在后面拼接分页参数
        PageHelper.startPage(queryParam.getPage(), queryParam.getPageSize());
        //Page<Emp> p = empMapper.list();
        // Page<Emp> p = empMapper.list(name, gender, begin, end);
        Page<Emp> p = empMapper.findByCondition(queryParam);
        // Page<Emp> p = (Page<Emp>) list;
        return new PageResult<>(p.getTotal(), p.getResult());
    }

    /**
     * 新增员工及工作经历
     *
     * @param emp 员工实体
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addEmpAndExprList(Emp emp) throws Exception {
        try {
            // 1.保存员工的基本信息
            // 补全实体
            LocalDateTime now = LocalDateTime.now();
            emp.setPassword("123456");
            emp.setCreateTime(now);
            emp.setUpdateTime(now);
            empMapper.insert(emp);
            //log.info("id:{}", emp.getId());

            // 手动制造异常
            // int i = 1/0;
            // 出编译时异常
           /* if(true) {
                throw new Exception();
            }*/
            // 2.保存员工工作经历信息
            // 为每条工作经历都补全empId
            // 健壮性：做出合理判断
            List<EmpExpr> exprList = getExprList(emp);
            if(CollUtil.isNotEmpty(exprList)) {
                empExprMapper.insertBatch(exprList);
            }
        } finally {
            EmpLog empLog = new EmpLog();
            empLog.setOperateTime(LocalDateTime.now());
            empLog.setInfo(JSONUtil.toJsonStr(emp));
            empLogService.save(empLog);
        }
    }

    /**
     * 根据ID批量删除员工和员工工作经历
     *
     * @param ids
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByIds(Integer[] ids) throws Exception {
        if(ArrayUtil.isNotEmpty(ids)) {
            // 1.根据员工ID列表查询头像的URL
            List<String> keys = empMapper.selectImagesByIds(ids);
            log.info("db keys:{}", keys);
            // 2.批量删除员工数据
            empMapper.deleteByIds(ids);
            // 3.批量删除员工关联的工作经历数据
            empExprMapper.deleteByEmpIds(ids);
            // 4.删除阿里云OSS关联的员工图片数据
            aliyunOSSOperator.deleteByUrls(keys);
        }

    }

    /**
     * 根据ID查询员工信息及工作经历信息
     *
     * @param id
     * @return
     */
    @Override
    public Emp findById(Integer id) {
        return empMapper.findById(id);
    }

    /**
     * 修改员工信息及工作经历信息
     *
     * @param emp
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Emp emp) {
        // 获取到原先没有改动的用户名 现在新的用户名，它俩不一样，才需要判断用户名是否重复
        Emp dbEmp = empMapper.findById(emp.getId());
        if(!StrUtil.equals(dbEmp.getUsername(), emp.getUsername())) {
            // 要对用户名及手机：判断是否重复
            Integer count = empMapper.countByUsername(emp.getUsername());
            if(count > 0) {
                throw new CustomException(emp.getUsername() + " 用户名已存在，请更换");
            }
        }
        //TODO 手机判重自己写
        // 1.修改员工基本信息
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.updateById(emp);
        // 2.删除之前员工工作经历
        empExprMapper.deleteByEmpIds(new Integer[]{emp.getId()});
        // 3.新增现在的员工工作经历
        List<EmpExpr> exprList = getExprList(emp);
        if(CollUtil.isNotEmpty(exprList)) {
            empExprMapper.insertBatch(exprList);
        }
    }

    @Override
    public List<Emp> list() {
        return empMapper.findAll();
    }

    /**
     * 登录
     *
     * @param loginDTO
     * @return
     */
    @Override
    public LoginVO login(LoginDTO loginDTO) {
        // 1.参数校验
        String username = loginDTO.getUsername();
        String password = loginDTO.getPassword();
        if(StrUtil.isBlank(username) || StrUtil.isBlank(password)) {
            throw new CustomException("用户名跟密码都必须填写！！");
            // return LoginVO.builder()
            //         .message("用户名跟密码都必须填写！！")
            //         .build();
        }
        // 2.处理逻辑
        // 2.1 根据用户名去查询数据库
        // select * from emp where username = ? limit 1
        Emp emp = empMapper.findByUsername(username);
        // 2.2 用户不存在
        if(ObjUtil.isNull(emp)) {
            throw new CustomException("用户名不存在，请联系管理员！！");
        }
        // 2.2 比对密码
        if(!StrUtil.equals(emp.getPassword(), password)) {
            throw new CustomException("用户名或密码不正确！！");
        }
        // 2.3 状态判断（无）
        // 3.封装数据
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", emp.getId());
        String token = JwtUtils.generateJwt(claims);
        return LoginVO.builder()
                .id(emp.getId())
                .name(emp.getName())
                .username(emp.getUsername())
                .token(token)
                .build();
    }

    /**
     * Ctrl+Alt+M 抽取方法
     * @param emp
     * @return
     */
    private List<EmpExpr> getExprList(Emp emp) {
        List<EmpExpr> exprList = emp.getExprList();
        if(CollUtil.isNotEmpty(exprList)) {
            exprList = exprList.stream()
                    // 修改集合中的属性值，收集后生效
                    .peek(item -> item.setEmpId(emp.getId()))
                    .toList();
        }
        return exprList;
    }
}
